View Javadoc
1 /************************************************************ 2 * Copyright * 3 * Portions of this software are Copyright (c) 1993 - 2002, * 4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew * 5 * - http://www.nevrona.com/Indy/ * 6 ************************************************************/ 7 package org.indy.socks; 8 9 import org.indy.IndyComponent; 10 11 import org.indy.io.IOHandler; 12 import org.indy.io.IndyIOException; 13 import org.indy.io.ReadTimedOutException; 14 15 import org.indy.util.IndyUtilities; 16 17 18 /*** 19 * Description of the Class 20 * 21 *@author owen 22 */ 23 public class SocksInfo extends IndyComponent { 24 /*** 25 * Description of the Field 26 */ 27 protected Authentication authentication = Authentication.NO_AUTHENTICATION; 28 29 /*** 30 * Description of the Field 31 */ 32 protected String host = null; 33 34 /*** 35 * Description of the Field 36 */ 37 protected int port = 0; 38 39 /*** 40 * Description of the Field 41 */ 42 protected String username = null; 43 44 /*** 45 * Description of the Field 46 */ 47 protected String password = null; 48 49 /*** 50 * Description of the Field 51 */ 52 protected Version version = Version.NOSOCKS; 53 54 /*** 55 * Description of the Field 56 */ 57 protected IOHandler ioHandler = null; 58 59 /*** 60 * Constructor for the IdSocksInfo object 61 * 62 *@param soInfo Description of the Parameter 63 */ 64 public SocksInfo(SocksInfo soInfo) { 65 this.authentication = soInfo.authentication; 66 this.host = soInfo.host; 67 this.username = soInfo.username; 68 this.password = soInfo.password; 69 this.port = soInfo.port; 70 this.version = soInfo.version; 71 } 72 73 /*** 74 * Constructor for the IdSocksInfo object 75 */ 76 public SocksInfo() { 77 } 78 79 /*** 80 * Sets the authentication attribute of the IdSocksInfo object 81 * 82 *@param newAuthentication The new authentication value 83 */ 84 public void setAuthentication(SocksInfo.Authentication newAuthentication) { 85 authentication = newAuthentication; 86 } 87 88 /*** 89 * Sets the host attribute of the IdSocksInfo object 90 * 91 *@param _host The new host value 92 */ 93 public void setHost(String _host) { 94 host = _host; 95 } 96 97 /*** 98 * Sets the port attribute of the IdSocksInfo object 99 * 100 *@param _port The new port value 101 */ 102 public void setPort(int _port) { 103 port = _port; 104 } 105 106 /*** 107 * Sets the username attribute of the IdSocksInfo object 108 * 109 *@param _username The new username value 110 */ 111 public void setUsername(String _username) { 112 username = _username; 113 } 114 115 /*** 116 * Sets the password attribute of the IdSocksInfo object 117 * 118 *@param _password The new password value 119 */ 120 public void setPassword(String _password) { 121 password = _password; 122 } 123 124 /*** 125 * Sets the socksVersion attribute of the IdSocksInfo object 126 * 127 *@param _version The new socksVersion value 128 */ 129 public void setSocksVersion(SocksInfo.Version _version) { 130 version = _version; 131 } 132 133 /*** 134 * Sets the ioHandler attribute of the IdSocksInfo object 135 * 136 *@param _ioHandler The new ioHandler value 137 */ 138 public void setIoHandler(IOHandler _ioHandler) { 139 ioHandler = _ioHandler; 140 } 141 142 /*** 143 * Gets the authentication attribute of the IdSocksInfo object 144 * 145 *@return The authentication value 146 */ 147 public SocksInfo.Authentication getAuthentication() { 148 return authentication; 149 } 150 151 /*** 152 * Gets the host attribute of the IdSocksInfo object 153 * 154 *@return The host value 155 */ 156 public String getHost() { 157 return host; 158 } 159 160 /*** 161 * Gets the port attribute of the IdSocksInfo object 162 * 163 *@return The port value 164 */ 165 public int getPort() { 166 return port; 167 } 168 169 /*** 170 * Gets the username attribute of the IdSocksInfo object 171 * 172 *@return The username value 173 */ 174 public String getUsername() { 175 return username; 176 } 177 178 /*** 179 * Gets the password attribute of the IdSocksInfo object 180 * 181 *@return The password value 182 */ 183 public String getPassword() { 184 return password; 185 } 186 187 /*** 188 * Gets the socksVersion attribute of the IdSocksInfo object 189 * 190 *@return The socksVersion value 191 */ 192 public Version getSocksVersion() { 193 return version; 194 } 195 196 /*** 197 * Description of the Method 198 * 199 *@param host Description of the Parameter 200 *@param port Description of the Parameter 201 *@throws IdSocksError Description of the Exception 202 */ 203 public void makeSocksConnection(String host, int port) 204 throws SocksException, ReadTimedOutException { 205 if ((version == Version.SOCKS4) || (version == Version.SOCKS4A)) { 206 makeSocks4Connection(host, port); 207 } 208 else if (version == Version.SOCKS5) { 209 makeSocks5Connection(host, port); 210 } 211 } 212 213 /*** 214 * Description of the Method 215 * 216 *@param host Description of the Parameter 217 *@param port Description of the Parameter 218 *@throws IdSocksError Description of the Exception 219 */ 220 public void makeSocks4Connection(String host, int port) 221 throws SocksException, ReadTimedOutException { 222 byte[] request = new byte[263]; 223 224 request[0] = 4; 225 request[1] = 1; 226 request[2] = (byte) (port & 0xFF00); 227 request[3] = (byte) (port & 0xFF); 228 229 int pos = 4; 230 231 if (version == Version.SOCKS4A) { 232 request[4] = 0; 233 request[5] = 0; 234 request[6] = 0; 235 request[7] = 1; 236 } 237 else { 238 /*** @todo NO java.net call here!! */ 239 240 //probably should delegate java.net call elsewhere 241 try { 242 java.net.InetAddress ia = java.net.InetAddress.getByName(host); 243 byte[] addr = ia.getAddress(); 244 245 request[4] = addr[0]; 246 request[5] = addr[1]; 247 request[6] = addr[2]; 248 request[7] = addr[3]; 249 } 250 catch (java.net.UnknownHostException uhe) { 251 //argghh 252 throw new SocksUnknownHostException("Unknown host " + host); 253 } 254 } 255 256 pos = 8; 257 258 System.arraycopy(username.getBytes(), 0, request, pos, username.length()); 259 pos += username.length(); 260 request[pos] = '\000'; 261 pos++; 262 263 if (version == Version.SOCKS4A) { 264 System.arraycopy(host.getBytes(), 0, request, pos, host.length()); 265 pos += host.length(); 266 request[pos++] = '\000'; 267 } 268 269 byte[] response = new byte[8]; 270 271 try { 272 ioHandler.write(request, 0, 8); 273 ioHandler.read(response, 0, 8); 274 } 275 catch (IndyIOException ioe) { 276 throw new SocksServerRespondException(IndyUtilities.getResourceString( 277 "RSSocksServerRespondError")); 278 } 279 280 switch (response[1]) { 281 case 90: 282 break; 283 284 //success, do nothing 285 case 91: 286 throw new SocksRequestFailedException(IndyUtilities.getResourceString( 287 "RSSocksRequestFailed")); 288 289 case 92: 290 throw new SocksRequestServerFailedException(IndyUtilities.getResourceString( 291 "RSSocksRequestServerFailed")); 292 293 case 93: 294 throw new SocksRequestIdentFailedException(IndyUtilities.getResourceString( 295 "RSSocksRequestIdentFailed")); 296 297 default: 298 throw new SocksUnknownException(IndyUtilities.getResourceString( 299 "RSSocksUnknownError")); 300 } 301 } 302 303 /*** 304 * Description of the Method 305 * 306 *@param host Description of the Parameter 307 *@param port Description of the Parameter 308 *@throws IdSocksError Description of the Exception 309 */ 310 public void makeSocks5Connection(String host, int port) 311 throws SocksException, ReadTimedOutException { 312 byte[] tmpBuf = new byte[255]; 313 314 if (authentication == Authentication.NO_AUTHENTICATION) { 315 tmpBuf[2] = 0x0; 316 } 317 else { 318 tmpBuf[2] = 0x2; 319 } 320 321 byte requestedAuthMethod = tmpBuf[2]; 322 323 tmpBuf[0] = 0x5; 324 325 326 // socks version 327 tmpBuf[1] = 0x1; 328 329 //number of possible authentication methods 330 int len = 2 + tmpBuf[1]; 331 332 try { 333 ioHandler.write(tmpBuf, 0, len); 334 ioHandler.read(tmpBuf, 0, 2); 335 } 336 catch (IndyIOException ioe) { 337 throw new SocksServerRespondException(IndyUtilities.getResourceString( 338 "RSSocksServerRespondError")); 339 } 340 341 byte serverAuthMethod = tmpBuf[1]; 342 343 if ((serverAuthMethod != requestedAuthMethod) || 344 (serverAuthMethod == 0xFF)) { 345 throw new SocksAuthMethodException(IndyUtilities.getResourceString( 346 "RSSocksAuthMethodError")); 347 } 348 349 if (authentication == Authentication.USERNAME_PASSWORD) { 350 if ((username == null) || (password == null)) { 351 //throw exception ?? 352 } 353 354 tmpBuf[0] = 0x1; 355 356 //length of subnegotiation; 357 int ulen = (username == null) ? 0 : username.length(); 358 359 tmpBuf[1] = (byte) ulen; 360 361 int pos = 2; 362 363 if ((ulen > 0) && (username != null)) { 364 System.arraycopy(username.getBytes(), 0, tmpBuf, pos, ulen); 365 } 366 367 pos += ulen; 368 369 int passlen = (password == null) ? 0 : password.length(); 370 371 tmpBuf[pos] = (byte) passlen; 372 pos++; 373 374 if ((passlen > 0) && (password != null)) { 375 System.arraycopy(password.getBytes(), 0, tmpBuf, pos, passlen); 376 } 377 378 pos += passlen; 379 380 try { 381 ioHandler.write(tmpBuf, 0, pos); 382 383 384 //send the username and password 385 ioHandler.read(tmpBuf, 0, 2); 386 } 387 catch (IndyIOException ioe) { 388 throw new SocksServerRespondException(IndyUtilities.getResourceString( 389 "RSSocksServerRespondError")); 390 } 391 392 if (tmpBuf[1] != 0x0) { 393 throw new SocksAuthException(IndyUtilities.getResourceString( 394 "RSSocksAuthError")); 395 } 396 } 397 398 399 //Connection process 400 tmpBuf[0] = 0x5; 401 402 403 //socks version 404 tmpBuf[1] = 0x1; 405 406 407 //connect method 408 tmpBuf[2] = 0x0; 409 410 411 //reserved 412 tmpBuf[3] = 0x3; 413 414 415 //Domain name - must find out out about all this 416 //address type: IP v4 Address 0x1 417 // Domain name 0x3 418 // IP v6 Address 0x4 419 tmpBuf[4] = (byte) host.length(); 420 421 int pos = 5; 422 423 if (host.length() > 0) { 424 System.arraycopy(host.getBytes(), 0, tmpBuf, pos, host.length()); 425 } 426 427 pos += host.length(); 428 429 430 //port 431 tmpBuf[pos] = (byte) (port & 0xFF00); 432 tmpBuf[pos++] = (byte) (port & 0xFF); 433 pos++; 434 435 try { 436 //send the connection packet 437 ioHandler.write(tmpBuf, 0, pos); 438 439 440 // Socks server replies on connect, this is the first part 441 ioHandler.read(tmpBuf, 0, 5); 442 } 443 catch (IndyIOException ioe) { 444 throw new SocksServerRespondException(IndyUtilities.getResourceString( 445 "RSSocksServerRespondError")); 446 } 447 448 switch (tmpBuf[1]) { 449 case 0: 450 break; 451 452 //success - do nothing 453 case 1: 454 throw new SocksServerGeneralException(IndyUtilities.getResourceString( 455 "RSSocksServerGeneralError")); 456 457 case 2: 458 throw new SocksServerPermissionException(IndyUtilities.getResourceString( 459 "RSSocksServerPermissionError")); 460 461 case 3: 462 throw new SocksServerNetUnreachableException(IndyUtilities.getResourceString( 463 "RSSocksServerNetUnreachableError")); 464 465 case 4: 466 throw new SocksServerHostUnreachableException(IndyUtilities.getResourceString( 467 "RSSocksServerHostUnreachableError")); 468 469 case 5: 470 throw new SocksServerConnectionRefusedException(IndyUtilities.getResourceString( 471 "RSSocksServerConnectionRefusedError")); 472 473 case 6: 474 throw new SocksServerTTLExpiredException(IndyUtilities.getResourceString( 475 "RSSocksServerTTLExpiredError")); 476 477 case 7: 478 throw new SocksServerCommandException(IndyUtilities.getResourceString( 479 "RSSocksServerCommandError")); 480 481 case 8: 482 throw new SocksServerAddressException(IndyUtilities.getResourceString( 483 "RSSocksServerAddressError")); 484 485 default: 486 throw new SocksUnknownException(IndyUtilities.getResourceString( 487 "RSSocksUnknownError")); 488 } 489 490 //type of destination address is domain name 491 switch (tmpBuf[3]) { 492 //IPv4 493 case 1: 494 len = 4 + 2; 495 496 break; 497 498 // 4 is for address and 2 is for port length 499 //FQDN 500 case 3: 501 len = tmpBuf[4] + 2; 502 503 break; 504 505 // 2 is for port length 506 //IPv6 507 case 4: 508 len = 16 + 2; 509 510 // 16 is for address and 2 is for port length 511 } 512 513 try { 514 // Socks server replies on connect, this is the second part 515 ioHandler.read(tmpBuf, 0, len - 1); 516 517 // 518 } 519 catch (IndyIOException ioe) { 520 throw new SocksServerRespondException(IndyUtilities.getResourceString( 521 "RSSocksServerRespondError")); 522 } 523 } 524 525 /*** 526 * Description of the Class 527 * 528 *@author owen 529 */ 530 public final static class Version { 531 /*** 532 * Description of the Field 533 */ 534 public final static Version NOSOCKS = new Version("No SOCKS"); 535 536 /*** 537 * Description of the Field 538 */ 539 public final static Version SOCKS4 = new Version("SOCKS 4"); 540 541 /*** 542 * Description of the Field 543 */ 544 public final static Version SOCKS4A = new Version("SOCKS 4A"); 545 546 /*** 547 * Description of the Field 548 */ 549 public final static Version SOCKS5 = new Version("SOCKS 5"); 550 private final String _desc; 551 552 private Version(String desc) { 553 _desc = desc; 554 } 555 556 /*** 557 * Description of the Method 558 * 559 *@return Description of the Return Value 560 */ 561 public String toString() { 562 return "SOCKS Version: " + _desc; 563 } 564 } 565 566 /*** 567 * Description of the Class 568 * 569 *@author owen 570 */ 571 public final static class Authentication { 572 /*** 573 * Description of the Field 574 */ 575 public final static Authentication NO_AUTHENTICATION = 576 new Authentication("None"); 577 578 /*** 579 * Description of the Field 580 */ 581 public final static Authentication USERNAME_PASSWORD = 582 new Authentication("Username-Password"); 583 private String _desc; 584 585 private Authentication(String desc) { 586 _desc = desc; 587 } 588 589 /*** 590 * Description of the Method 591 * 592 *@return Description of the Return Value 593 */ 594 public String toString() { 595 return "SOCKS Authentication: " + _desc; 596 } 597 } 598 }

This page was automatically generated by Maven